activiti和设计模式(3)
提到activiti的核心业务的组织方式,就不得不提到,BPMN规范中各个图形代表的意义,各个参数的设置等等纷杂的问题。 中间我们关注的是activiti对bpmn规范中各个图形对应的对象组织方式,以及其中的设计模式。更准确的说是继承,扩展和组合的使用定义。
首先是:流程定义的解析,我们可以知道总体的模型对应的类是:BpmnModel,但是这个模式是怎么得到的?
BpmnXMLConverter converter = new BpmnXMLConverter();
bpmnModel = converter.convertToBpmnModel(streamSource, validateSchema, enableSafeBpmnXml, encoding);
//使用fasterxml 来解析xml
if (ELEMENT_DEFINITIONS.equals(xtr.getLocalName())) {
definitionsParser.parse(xtr, model);
} else if (ELEMENT_RESOURCE.equals(xtr.getLocalName())) {
resourceParser.parse(xtr, model);
} else if (ELEMENT_SIGNAL.equals(xtr.getLocalName())) {
signalParser.parse(xtr, model);
} else if (ELEMENT_MESSAGE.equals(xtr.getLocalName())) {
messageParser.parse(xtr, model);
}
//具体针对各个BPMN规范的解析
protected BpmnEdgeParser bpmnEdgeParser = new BpmnEdgeParser();
protected BpmnShapeParser bpmnShapeParser = new BpmnShapeParser();
protected DefinitionsParser definitionsParser = new DefinitionsParser();
protected DocumentationParser documentationParser = new DocumentationParser();
protected ExtensionElementsParser extensionElementsParser = new ExtensionElementsParser();
protected ImportParser importParser = new ImportParser();
protected InterfaceParser interfaceParser = new InterfaceParser();
protected ItemDefinitionParser itemDefinitionParser = new ItemDefinitionParser();
protected IOSpecificationParser ioSpecificationParser = new IOSpecificationParser();
protected DataStoreParser dataStoreParser = new DataStoreParser();
protected LaneParser laneParser = new LaneParser();
protected MessageParser messageParser = new MessageParser();
protected MessageFlowParser messageFlowParser = new MessageFlowParser();
protected MultiInstanceParser multiInstanceParser = new MultiInstanceParser();
protected ParticipantParser participantParser = new ParticipantParser();
protected PotentialStarterParser potentialStarterParser = new PotentialStarterParser();
protected ProcessParser processParser = new ProcessParser();
protected ResourceParser resourceParser = new ResourceParser();
protected SignalParser signalParser = new SignalParser();
protected SubProcessParser subProcessParser = new SubProcessParser();
我们最后看一下,BpmnModel的组成:
protected Map<String, List<ExtensionAttribute>> definitionsAttributes =
new LinkedHashMap\<String, List<ExtensionAttribute>\>();
protected List<Process> processes = new ArrayList<Process>();
protected Map<String, GraphicInfo> locationMap = new LinkedHashMap<String, GraphicInfo>();
protected Map<String, GraphicInfo> labelLocationMap = new LinkedHashMap<String, GraphicInfo>();
protected Map<String, List<GraphicInfo>> flowLocationMap = new LinkedHashMap<String, List<GraphicInfo>>();
protected List<Signal> signals = new ArrayList<Signal>();
protected Map<String, MessageFlow> messageFlowMap = new LinkedHashMap<String, MessageFlow>();
protected Map<String, Message> messageMap = new LinkedHashMap<String, Message>();
protected Map<String, String> errorMap = new LinkedHashMap<String, String>();
protected Map<String, ItemDefinition> itemDefinitionMap = new LinkedHashMap<String, ItemDefinition>();
protected Map<String, DataStore> dataStoreMap = new LinkedHashMap<String, DataStore>();
protected List<Pool> pools = new ArrayList<Pool>();
protected List<Import> imports = new ArrayList<Import>();
protected List<Interface> interfaces = new ArrayList<Interface>();
protected List<Artifact> globalArtifacts = new ArrayList<Artifact>();
protected List<Resource> resources = new ArrayList<Resource>();
protected Map<String, String> namespaceMap = new LinkedHashMap<String, String>();
protected String targetNamespace;
protected List<String> userTaskFormTypes;
protected List<String> startEventFormTypes;
protected int nextFlowIdCounter = 1;
你会发现,在调试的时候老出现的Activity之类的并没有出现,那么BpmnModel和ProcessDefinitionImpl是怎么关联起来的呢?同样是在BpmnParse中,可以发现:
public BpmnParse execute() {
。。。。。。
// Validation successfull (or no validation)
createImports();
createItemDefinitions();
createMessages();
createOperations();
transformProcessDefinitions();
。。。。。。
}
具体的操作是在:org.activiti.engine.impl.bpmn.parser.BpmnParse.processDI()中,主要的代码是:
// Parse diagram interchange information
ProcessDefinitionEntity processDefinition = getProcessDefinition(process.getId());
if (processDefinition != null) {
processDefinition.setGraphicalNotationDefined(true);
for (String shapeId : bpmnModel.getLocationMap().keySet()) {
if (processDefinition.findActivity(shapeId) != null) {
createBPMNShape(shapeId, bpmnModel.getGraphicInfo(shapeId), processDefinition);
}
}
for (String edgeId : bpmnModel.getFlowLocationMap().keySet()) {
if (bpmnModel.getFlowElement(edgeId) != null) {
createBPMNEdge(edgeId, bpmnModel.getFlowLocationGraphicInfo(edgeId));
}
}
从这里我们可以看出来:BpmnModel只要支持的Bpmn的规范,支持的是xml中定义的各个图形的对象,以及对象的属性。ProcessDefinitionEntity主要的是流程运转的过程中的对象,这点从类的命名上面也可以看出来。
这里想说的是设计模式:组合模式(Composite pattern),以及解析过程中的工程模式(Abstract factory pattern)。
组合模式:
首先是每一个元素都会含有实行,在activiti中属性抽象为一个接口,
所有的基础元素都会实现该接口:
org.activiti.bpmn.model.HasExtensionAttribute
public abstract class BaseElement implements HasExtensionAttributes
public abstract class FlowElement extends BaseElement implements HasExecutionListeners
BaseElement 被设计为抽象的类型,这个感觉基础元素,不会出现在xml定义中,也就符合了抽象类:不能被实例化的特性。
BaseElement的继承的体系,如附件所示:
其中我们比较属性的Usertask,Process的集成体系也如附件中体现:
单独的把FlowElement列出来,是因为抽象类FlowElement中有一个比较好玩的,也是比较重要的方法: public abstract FlowElement clone();
可以直接的克隆一个元素出来,在后期的扩展中,这个是比较有用的一个方法,在继承体系,所有的元素都实现了这个方法,也就为了后面的扩展提供了基础。
上面的BpmnModel就是典型的组合模式,但是在继承体系中,也是含有组合的,最容易理解的莫过于子流程的定义了,即:
public class SubProcess extends Activity implements FlowElementsContainer {
protected List<FlowElement> flowElementList = new ArrayList<FlowElement>();
protected List<Artifact> artifactList = new ArrayList<Artifact>();
protected List<ValuedDataObject> dataObjects = new ArrayList<ValuedDataObject>();
在BPMN的解析的过程中,使用到了抽象工厂的类:
public interface BpmnParseFactory {
BpmnParse createBpmnParse(BpmnParser bpmnParser);
}
默认的工程类:
public class DefaultBpmnParseFactory implements BpmnParseFactory {
public BpmnParse createBpmnParse(BpmnParser bpmnParser) {
return new BpmnParse(bpmnParser);
}
}
使用的情况:
if (bpmnParseFactory == null) {
bpmnParseFactory = new DefaultBpmnParseFactory();
}
个人感觉有点过度设计的感觉,但是为了扩展,也是无可厚非。
- 上一篇 activiti和设计模式(2.1)
- 下一篇 activiti和设计模式(4)